package cn.changein.framework.elasticsearch.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.json.JacksonJsonParser;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class JsonUtil {
    static ObjectMapper om = new ObjectMapper();
    static JacksonJsonParser jsonParser = new JacksonJsonParser();

    static {
        om.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        om.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    }

    public static String toJson(Object obj) {
        try {
            return om.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static <T> T parse(String value, Class<T> clz) {
        try {
            return om.readValue(value, clz);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static <T> T parse(String value, T type) {
        try {
            return om.readValue(value, (JavaType) type);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Map<String, Object> parseMap(String json) {
        return jsonParser.parseMap(json);
    }

    /**
     * @Description: 解析 map stringJson 转换成 Map<String, List<T>>
     * @Date:2020/12/19 20:34
     * @Param: [value, type]

     */
    public static <T> Map<String, List<T>> parseMap(String value, Class<T> type) {
        try {
            Map<String, List<T>> mapList = parse(value, Map.class);
            for (Map.Entry<String, List<T>> entry : mapList.entrySet()) {
                //List<String,Object> 转 Object
                List<T> valueList = entry.getValue();
                List<T> resultList = new ArrayList<T>();
                Iterator<T> iterator = valueList.iterator();
                while (iterator.hasNext()) {//String ,Object
                    T map = iterator.next();
                    T resultObj = mapToObj(map, type);
                    resultList.add(resultObj);
                }
                entry.setValue(resultList);
            }
            return mapList;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @Description: 转换成list
     * @Date:2020/12/19 20:35
     * @Param: [jsonArrayStr, clazz]

     */
    public static <T> List<T> parseArray(String jsonArrayStr, Class<T> clazz) {
        try {
            List<T> list = om.readValue(jsonArrayStr, new TypeReference<List<T>>() {
            });
            Iterator<T> iterator = list.iterator();
            List<T> resultList = new ArrayList<T>();
            while (iterator.hasNext()) {
                T map = iterator.next();
                T result = mapToObj(map, clazz);
                resultList.add(result);
            }
            return resultList;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ArrayList<T>();
    }

    /**
     * @Description: map转换成obj
     * @Date:2020/12/19 21:08
     * @Param: [map, clazz]

     */
    public static <T> T mapToObj(T map, Class<T> clazz) {
        String str = toJson(map);
        T obj = parse(str, clazz);
        return obj;
    }
}
